package com.timeriver.utils;

import org.apache.commons.lang3.StringUtils;

/**
 * 无限制对称加密策略
 */
public class AES256Util {
    /**
     * 密钥：256位32字节。可以在后台随机生成
     */
    public static String SECURE_KEY = null;
    private static final int AES_LENGTH_BYTE = 32;

    /**
     * 初始向量IV，初始向量IV的长度规定为128位16个字节, 初始向量的来源为随机生成.
     */
    private static String VECTOR_128 = null;
    private static final int VI_LENGTH_BYTE = 16;

    private static final String AES = "AES";

    /**
     * 加密解密算法/加密模式/填充方式
     */
    private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";

    private static java.util.Base64.Encoder base64Encoder = java.util.Base64.getEncoder();
    private static java.util.Base64.Decoder base64Decoder = java.util.Base64.getDecoder();

    static {
        /** 设置为：无限制加密策略 */
        java.security.Security.setProperty("crypto.policy", "unlimited");
    }

    private static void initCheck() {
        if (StringUtils.isEmpty(VECTOR_128)) {
            VECTOR_128 = UUIDUtil.getSecureRandom(VI_LENGTH_BYTE);
        }
        if (StringUtils.isEmpty(SECURE_KEY)) {
            SECURE_KEY = UUIDUtil.getSecureRandom(AES_LENGTH_BYTE);
        }
    }

    /**
     * AES加密
     * @param content 待加密内容
     * @return
     */
    public static String encode(String content) {
         try {
             initCheck();
             javax.crypto.SecretKey secretKey = new javax.crypto.spec.SecretKeySpec(SECURE_KEY.getBytes(), AES);
             javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CIPHER_ALGORITHM);
             cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, secretKey, new javax.crypto.spec.IvParameterSpec(VECTOR_128.getBytes()));

             // 获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
             byte[] byteEncode = content.getBytes(java.nio.charset.StandardCharsets.UTF_8);

             // 根据密码器的初始化方式加密
             byte[] byteAES = cipher.doFinal(byteEncode);

             // 将加密后的数据转换为字符串
             return base64Encoder.encodeToString(byteAES);
         } catch (Exception e) {
             e.printStackTrace();
         }
         return null;
    }

    /**
     * AES解密
     * @param content 待解密内容
     * @return
     */
    public static String decode(String content) {
         try {
             initCheck();
             javax.crypto.SecretKey secretKey = new javax.crypto.spec.SecretKeySpec(SECURE_KEY.getBytes(), AES);
             javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(CIPHER_ALGORITHM);
             cipher.init(javax.crypto.Cipher.DECRYPT_MODE, secretKey, new javax.crypto.spec.IvParameterSpec(VECTOR_128.getBytes()));

             // 将加密并编码后的内容解码成字节数组
             byte[] byteContent = base64Decoder.decode(content);
             // 解密
             byte[] byteDecode = cipher.doFinal(byteContent);
             return new String(byteDecode, java.nio.charset.StandardCharsets.UTF_8);
         } catch (Exception e) {
             e.printStackTrace();
         }
         return null;
    }
}
